#pragma once
#include "pch.h"
#include "Common.h"
#include <CGAL/Surface_mesh.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Unique_hash_map.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Constrained_placement.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Midpoint_placement.h>
namespace AutomatedSurfaceReconstruction 
{
	class CLocalEdgeCollapseMeshSimplification
	{
	public:
		CLocalEdgeCollapseMeshSimplification(const CGALMeshType& vMesh, const std::size_t vExpectedFacetNum) :m_Mesh(vMesh), m_ExpectedFacetNum(vExpectedFacetNum) {};
		~CLocalEdgeCollapseMeshSimplification() = default;

		bool simplifyMesh();
		bool simplifyMeshLocally(const CGALPointSetType& vConstrainedPointSet);

		void setMesh(const CGALMeshType& vMesh) { m_Mesh = vMesh; }
		const auto getMesh() const { return m_Mesh; }
		void setExpectedFacetNum(const std::size_t vExpectedFacetNum) { m_ExpectedFacetNum = vExpectedFacetNum; }
		const auto getExpectedFacetNum() const { return m_ExpectedFacetNum; }
	private:
		struct SConstrainedEdgeMap
		{
			typedef boost::readable_property_map_tag      category;
			typedef bool                                  value_type;
			typedef bool                                  reference;
			typedef EdgeDescriptor                       key_type;
			SConstrainedEdgeMap(const CGAL::Unique_hash_map<key_type, bool>& vConstraintEdges)
				: m_ConstraintEdges(vConstraintEdges)
			{}
			value_type operator[](const key_type& e) const { return is_constrained(e); }
			friend  value_type get(const SConstrainedEdgeMap& m, const key_type& k) { return m[k]; }
			bool is_constrained(const key_type& e) const { return m_ConstraintEdges[e] == true; }
		private:
			const CGAL::Unique_hash_map<key_type, bool>& m_ConstraintEdges;
		};
		void __getConstrainedPointIndex(const CGALPointSetType& vConstrainedPointSet);
		bool __specifyConstrainedEdges();
		bool __simplifyLocalMesh();


		CGALMeshType m_Mesh;
		std::size_t m_ExpectedFacetNum = 0;
		std::vector<std::uint32_t> m_ConstrainedVertexIndexSet;
		CGAL::Unique_hash_map<EdgeDescriptor, bool> m_ConstrainedEdges;
	};
}